package module;

import entity.ConfigFile;
import entity.LocalVideoConfig;
import entity.VideoItem;
import lombok.extern.slf4j.Slf4j;
import utils.json.VideoStateUtil;
import utils.json.InitConfig;
import utils.rsshub.RSSHubUtil;
import utils.runnable.YouGetDownloadRunnable;
import utils.threadpool.ThreadPoolUtil;

import java.util.ArrayList;
import java.util.List;
import java.util.TimerTask;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * RSSHub功能模块，实现轮询查询投币（收藏）的B站视频列表。并且加入下载队列。
 */
@Slf4j
public class RSSHub {
    private static final ConfigFile configFile = InitConfig.getInstance().getConfig();
    private static final VideoStateUtil videoStateUtil = VideoStateUtil.getInstance();
    private static final LocalVideoConfig localVideoConfig = videoStateUtil.getLocalVideoConfig();
    private static final ScheduledExecutorService service = ThreadPoolUtil.getInstance().getTimerThreadPool();

    /**
     * 创建定时任务，每小时执行一次。拉取ConfigFile.RSSHub.Type配置的一类视频，并加入下载队列。
     */
    public static void startRSSHub() {
        log.info(InitConfig.RSSHUB_DELAY + "分钟后开始下载配置的视频类别。任务执行间隔时间：" + InitConfig.PERIOD + "分钟。");
        service.scheduleAtFixedRate(new RSSHubTimerTask(configFile.getRSSHub().getType()), InitConfig.RSSHUB_DELAY, InitConfig.PERIOD, TimeUnit.MINUTES);
    }

    private static class RSSHubTimerTask extends TimerTask {

        /**
         * The action to be performed by this timer task.
         */
        private final String type;

        @Override
        public void run() {
            //任务执行前先遍历本地下载文件夹，避免重复下载。
            videoStateUtil.parseLocalVideoConfigFileVideoList();
            log.info("开始处理本地下载任务。。。");
            switch (type) {
                case "fav":
                    List<VideoItem> favVideo = RSSHubUtil.getFavVideo();
                    removeDuplicate(favVideo);
                    break;
                case "coin":
                    List<VideoItem> coinVideo = RSSHubUtil.getCoinVideo();
                    removeDuplicate(coinVideo);
                    break;
                case "all":
                    List<VideoItem> allVideoList = new ArrayList<>();
                    allVideoList.addAll(RSSHubUtil.getFavVideo());
                    allVideoList.addAll(RSSHubUtil.getCoinVideo());
                    removeDuplicate(allVideoList);
                    break;
            }
            //执行下载队列
            addYouGetDownloadQueue();
            try {
                Thread.sleep(5 * 1000);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            log.info("本地下载任务处理完成，开始保存本地配置文件。");
            VideoStateUtil.saveConfigToFile();
        }

        public RSSHubTimerTask(String type) {
            this.type = type;
        }

        /**
         * 执行下载命令
         */
        private static void addYouGetDownloadQueue() {
            List<VideoItem> videoItems = localVideoConfig.getVideos();
            for (VideoItem item : videoItems) {
                switch (item.getIsDownload()) {
                    case 0:
                        log.info("视频标题：" + item.getTitle() + "，状态：成功添加到本地下载队列。");
                        ThreadPoolUtil.getInstance().getDownloadThreadPool().submit(new YouGetDownloadRunnable(item.getLink()));
                        item.setIsDownload(1);
                        break;
                    case 1:
                        log.info("视频标题：" + item.getTitle() + "，状态：本地下载中。");
                        break;
                    case 2:
                        log.info("视频标题：" + item.getTitle() + "，状态：本地已下载。");
                        break;
                }
                try {
                    //每个处理任务之间间隔3秒。
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }

        /**
         * 去重添加List
         *
         * @param list 要添加的List集合
         */
        private static void removeDuplicate(List<VideoItem> list) {
            List<VideoItem> localVideoConfigVideos = localVideoConfig.getVideos();
            for (VideoItem i : list) {
                boolean flag = true;
                for (VideoItem j : localVideoConfigVideos) {

                    if (i.getTitle().equals(j.getTitle()) && i.getLink().equals(j.getLink())) {
                        flag = false;
                        break;
                    }

                }
                if (flag) {
                    localVideoConfigVideos.add(i);
                }
            }
        }
    }

}
